package org.aurora.remote;

import org.aurora.remote.protocol.RemoteRequest;
import org.aurora.remote.protocol.RemoteResponse;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class ResponseFuture {

    private volatile RemoteRequest request;

    private volatile RemoteResponse response;

    private volatile SendCallback sendCallback;

    private volatile WaitResponseType waitResponseType;

    private volatile boolean requestSuccess  = false;

    private CountDownLatch countDownLatch = new CountDownLatch(1);

    public ResponseFuture(WaitResponseType waitResponseType) {
        this.waitResponseType = waitResponseType;
    }

    public ResponseFuture(WaitResponseType waitResponseType, RemoteRequest request, SendCallback sendCallback) {
        this.waitResponseType = waitResponseType;
        this.request = request;
        this.sendCallback = sendCallback;
    }

    public WaitResponseType getWaitResponseType() {
        return waitResponseType;
    }

    public void setWaitResponseType(WaitResponseType waitResponseType) {
        this.waitResponseType = waitResponseType;
    }

    public void putResponse(RemoteResponse response) {
        this.response = response;
        this.countDownLatch.countDown();
    }

    public RemoteResponse waitResponse(long timeout) throws InterruptedException {
        this.countDownLatch.await(timeout, TimeUnit.MILLISECONDS);
        return response;
    }

    public void requestSuccess() {
        this.requestSuccess = true;
    }

    public void requestFail() {
        this.requestSuccess = false;
        this.countDownLatch.countDown();
    }

    public SendCallback getSendCallback() {
        return sendCallback;
    }

    public void setSendCallback(SendCallback sendCallback) {
        this.sendCallback = sendCallback;
    }

    public RemoteRequest getRequest() {
        return request;
    }

    public void setRequest(RemoteRequest request) {
        this.request = request;
    }

    public boolean isRequestSuccess() {
        return requestSuccess;
    }

    public void setRequestSuccess(boolean requestSuccess) {
        this.requestSuccess = requestSuccess;
    }
}
